<?php
/***********************************************************************
 * @package    	IvanEngine
 * @subpackage 	Core
 * @author     	Ivan <ivanzx@msn.com>
 * @created    	2010-05-15
 ***********************************************************************/
if(defined("IVANENGINE_CORE_EVENT_EVENT"))
	die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_EVENT_EVENT", true);

require_once (dirname(__FILE__).'/../Common.php');
require_once (dirname(__FILE__).'/EventSlot.php');
require_once (dirname(__FILE__).'/EventArgs.php');

class CEvent extends CObject 
{
	protected $m_eventList	= null;
	protected $m_enable		= true;
	
	public function __construct() 
	{
		parent::__construct ();
		$this->m_eventList	= new CMap();
	}
	
	public function __destruct() 
	{
		unset($this->m_eventList);
		parent::__destruct ();
	}
	
	public function AddEvent($evtName)
	{
		if( $this->m_eventList->Get($evtName) == null )
		{
			$this->m_eventList->Add($evtName, new CVector());
		}
	}
	
	public function RemoveEvent($evtName)
	{
		$this->m_eventList->Remove($evtName);
	}
	
	public function RemoveAllEvent()
	{
		$this->m_eventList->Clear();
	}
	
	public function EnableEvent($enable)
	{
		$this->m_enable	= (bool)$enable;
	}
	
	public function IsEnableEvent()
	{
		return (bool)$this->m_enable;
	}
	
	public function Subscribe($evtName,CEventCallBack $callback)
	{
		if( $callback == null )
		{
			throw new CException("callback parameter of function Subscribe can not is null.");
		}
		else
		{
			$event	= $this->m_eventList->Get($evtName);
			if( $event == null )
			{
				throw new CException("Must be used prior to an event Subscribe to enable this event AddEvent");
			}else{
				$event->PushBack(new CEventSlot($callback));
			}
		}
	}
	
	public function FireEvent($evtName, CEventArgs $evtArgs)
	{
		$event	= $this->m_eventList->Get($evtName);
		if( $event == null )
		{
			throw new CException("Must be used prior to an event FireEvent to enable this event AddEvent");
		}else{
			$begin = $event->Begin();
			$evtArgs->evtName	= $evtName;
			while($begin->IsValid())
			{
				$evtSlot	= $begin->Value();
				$callback	= $evtSlot->GetCallBack();
				if( $evtSlot->IsConnect() )
				{
					if($callback->GetObject() == null){
						$evtArgs->result  |= call_user_func($callback->GetMethod(), $evtArgs);
					}else{
						$evtArgs->result  |= call_user_func(array($callback->GetObject(), $callback->GetMethod()), $evtArgs);
					}
				}
				$begin->Next();
			}
		}
	}
}

?>